#ifndef 栈测试
#define 栈测试

#include "链栈.h"
#include "顺序栈.h"
#include <catch2.hpp>

TEST_CASE("顺序栈")
{
    SqStack<int> s;
    InitStack(s);

    SECTION("初始化")
    {
        REQUIRE(s.top == -1);
    }

    SECTION("判栈空")
    {
        REQUIRE(StackEmpty(s));
        REQUIRE(Push(s, 10));
        REQUIRE_FALSE(StackEmpty(s));
    }

    SECTION("进栈")
    {
        REQUIRE(Push(s, 3));
        REQUIRE(Push(s, 2));
    }

    SECTION("出栈")
    {
        int x;
        REQUIRE_FALSE(Pop(s, x));
        REQUIRE(Push(s, 3));
        REQUIRE(Pop(s, x));
        REQUIRE_FALSE(Pop(s, x));

        REQUIRE(Push(s, 2));
        REQUIRE(Push(s, 1));
        REQUIRE(Push(s, 0));

        REQUIRE(Pop(s, x));
        REQUIRE(x == 0);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 1);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 2);
        REQUIRE_FALSE(Pop(s, x));
    }

    SECTION("读取栈元素")
    {
        int x;
        REQUIRE_FALSE(GetTop(s, x));
        REQUIRE(Push(s, 5));
        REQUIRE(Push(s, 4));
        REQUIRE(Push(s, 3));
        REQUIRE(Push(s, 2));
        REQUIRE(Push(s, 1));
        REQUIRE(Push(s, 0));

        REQUIRE(Pop(s, x));
        REQUIRE(x == 0);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 1);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 2);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 3);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 4);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 5);
    }
}

TEST_CASE("链栈")
{
    typedef LinkNode<int> LiStack;
    LiStack *s = new LiStack;
    InitStack(s);

    SECTION("初始化")
    {
        REQUIRE(s->next == nullptr);
    }

    SECTION("判栈空")
    {
        REQUIRE(StackEmpty(s));
    }
    SECTION("进栈")
    {
        REQUIRE(Push(s, 2));
        REQUIRE(Push(s, 1));
    }
    SECTION("出栈")
    {
        int x;
        REQUIRE_FALSE(Pop(s, x));
        REQUIRE((Push(s, 2) && Push(s, 1)));
        REQUIRE((Pop(s, x) && Pop(s, x)));
        REQUIRE_FALSE(Pop(s, x));
    }

    SECTION("读取栈元素")
    {
        int x;

        Push(s, 2);
        Push(s, 1);

        REQUIRE(Pop(s, x));
        REQUIRE(x == 1);
        REQUIRE(Pop(s, x));
        REQUIRE(x == 2);
        REQUIRE_FALSE(Pop(s, x));
    }

    SECTION("销毁栈")
    {
        LiStack *p = s;
        DestoryStack(s);
        REQUIRE(s == nullptr);

        REQUIRE(p->next == nullptr);
        Push(p, 3);
        Push(p, 2);
        Push(p, 1);
        Push(p, 0);
        DestoryStack(p);

        REQUIRE(p == nullptr);
    }
}

#endif